package com.backpackerxl.blog.service.impl;

import com.backpackerxl.blog.dao.CommentRepository;
import com.backpackerxl.blog.model.Comment;
import com.backpackerxl.blog.service.CommentService;
import com.backpackerxl.blog.vomodel.BlogCount;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Author by：Backpackersxl
 * Date: 2021/5/11/011
 * Time: 19:20
 **/
@Service
public class CommentServiceImp implements CommentService {
    private final CommentRepository commentRepository;

    public CommentServiceImp(CommentRepository commentRepository) {
        this.commentRepository = commentRepository;
    }

    @Transactional
    @Override
    public void saveComment(Comment comment) {
        Long parentCommentId = comment.getParentComment().getId();
        if (parentCommentId != -1) {
            comment.setParentComment(commentRepository.findById(parentCommentId).orElse(null));
        } else {
            comment.setParentComment(null);
        }
        comment.setCretateTime(new Date());
        commentRepository.save(comment);
    }

    @Override
    public List<Comment> listCommentByBlogId(Long blogId) {
        Sort sort = Sort.by("cretateTime");
        List<Comment> comments = commentRepository.findByBlogId(blogId, sort);
        return eachComment(comments);
    }

    /**
     * 组合评论信息
     *
     * @param comments 评论
     * @return 评论信息
     */
    private List<Comment> eachComment(List<Comment> comments) {
        List<Comment> pares = comments.stream().filter(comment -> comment.getParentComment() == null).collect(Collectors.toList());
        List<Long> ids = new ArrayList<>();
        List<Comment> temp = new ArrayList<>();
        for (Comment tg : pares) {
            tg.setReplyComment(temp);
            for (Comment cb : comments) {
                if (cb.getParentComment() == null || ids.contains(cb.getId())) {
                    continue;
                }
                if (Objects.equals(cb.getParentComment().getId(), tg.getId())) {
                    cb.setParentComment(tg);
                    tg.getReplyComment().add(cb);
                    ids.add(cb.getId());
                } else if (tg.getReplyComment().size() > 0) {
                    temp = new ArrayList<>(tg.getReplyComment());
                    for (Comment cof : temp) {
                        if (Objects.equals(cb.getParentComment().getId(), cof.getId())) {
                            cb.setParentComment(cof);
                            tg.getReplyComment().add(cb);
                            ids.add(cb.getId());
                        }
                    }
                }
            }
            temp = new ArrayList<>();
        }
        return pares;
    }

    @Override
    public Page<Comment> findAll(Pageable pageable) {
        return commentRepository.findAll(pageable);
    }

    @Override
    public void deleteComment(Long id) {
        commentRepository.deleteById(id);
    }

    @Override
    public Page<Comment> listComment(String query, Pageable pageable) {
        return commentRepository.findByQuery(query, pageable);
    }

    @Override
    public Long countComment() {
        return commentRepository.count();
    }

    @Override
    public List<BlogCount> listCommentCount() {
        return commentRepository.findCountComment();
    }
}
